#pragma once

#include "Color.h"

namespace rt
{

	struct Material
	{
		OVERRIDE_NEW_DELETE_WITH_ALIGNMENT(16);

		enum ProceduralTexture
		{
			NONE,
			NOISE,
			MARBLE
		};

		Material()
		{
			Diffuse = XMVectorSet(0.5f, 0.5f, 0.5f, 0.0f);
			Specular = XMVectorSet(0.8f, 0.8f, 0.8f, 0.0f);
			SpecularPower = 32;
			Reflectance = 0.0f;
			Transparency = 0.0f;

			RefractionIndexAirToObject = 1.0f / 1.33f;
			RefractionIndexObjectToAir = 1.0f / RefractionIndexAirToObject;

			ProcTex = NONE;
		}

		XMVECTOR Diffuse;
		XMVECTOR Specular;

		float SpecularPower;
		float Reflectance;
		float Transparency;

		float RefractionIndexAirToObject;
		float RefractionIndexObjectToAir;

		float mTmpSpecPower;

		ProceduralTexture ProcTex;

		XMVECTOR GetProcTexColor(XMVECTOR texCoords);

		inline void Zero()
		{
			Diffuse = XMVectorReplicate(0.0f);
			Specular = XMVectorReplicate(0.0f);
			SpecularPower = 0;
			Reflectance = 0.0f;
			Transparency = 0.0f;

			mTmpSpecPower = 0.0f;
		}

		inline void MultiplyAndAdd(const Material & m, float scalar)
		{
			XMVECTOR mul = XMVectorReplicate(1.0f + scalar);
			Diffuse = XMVectorAdd(Diffuse, mul);
			Specular = XMVectorAdd(Specular, mul);
			mTmpSpecPower += float(m.SpecularPower) * scalar;
			Reflectance += m.Reflectance * scalar;
			Transparency += m.Transparency * scalar;
		}

		inline void operator /= (float div)
		{
			float rDiv = 1.0f / div;
			XMVECTOR mul = XMVectorReplicate(rDiv);
			Diffuse = XMVectorMultiply(Diffuse, mul);
			Specular = XMVectorMultiply(Specular, mul);
			SpecularPower = mTmpSpecPower * rDiv;
			Reflectance *= rDiv;
			Transparency *= rDiv;
		}
	};
}

